#!/bin/csh -f

#
# Options.
#

set isock_server     = 'isock_server'
set isock_port       = 3333
set isock_name       = `uname -n | sed 's/.rfo.atmel.com$//'`
set isock_host       = `/sbin/ifconfig eth0 | perl -nle 'print $1 if /inet addr:(\S+)/'`

set restart          = ''
set restart_delay    = 10

if ( -f .script_isock && ( "$argv" =~ *-dot* || "$argv" =~ *--dot* ) ) then
  set argv0 = `cat .script_isock | perl -ne 's,^(\./)?script/isock ,, ; print'`
  set argv1 = "$argv"
  set argv  = ( $argv0 $argv1 )
endif

set dot_script_isock = `echo "$0 $argv" | perl -ne 's/ +-?-(dot|force|kill|pull)//g ; print'`

set argv2 = ""

while ( "x$1" != "x" )
  switch ( "$1" )
    case  -port:
    case --port:
      shift
      set isock_port = $1
      breaksw
    
    case  -sock_root:
    case --sock_root:
      shift
      set sock_root = $1
      breaksw
    
    case  -work_root:
    case --work_root:
      shift
      set work_root = $1
      breaksw
    case  -isock_db:
    case --isock_db:
      shift
      set isock_db = $1
      breaksw
    
    case  -parallel:
    case --parallel:
      shift
      set isock_parallel = $1
      breaksw
    
    case  -ignore_atp:
    case --ignore_atp:
      setenv SOCK_IGNORE_ATP 1
      breaksw
    
    case  -dummy:
    case --dummy:
      set dummy = 'yes'
      breaksw
    
    case  -setup:
    case --setup:
      set setup = 'yes'
      breaksw
    
    case  -restart:
    case --restart:
      set restart = 'yes'
      breaksw
    
    case  -restart_delay:
    case --restart_delay:
      shift
      set restart_delay = $1
      breaksw
    
    case  -debug:
    case --debug:
      set debug = 'yes'
      breaksw
    
    case  -devel:
    case --devel:
      set devel = 'yes'
      breaksw
    
    case  -fork:
    case --fork:
      set fork = 'yes'
      breaksw
    
    case  -proxy:
    case --proxy:
      set proxy = 'yes'
      breaksw
    
    case  -hup:
    case --hup:
      set hup = 'yes'
      breaksw
    
    case  -kill:
    case --kill:
      set kill = 'yes'
      breaksw
    
    case  -tail:
    case --tail:
      set tail = 'yes'
      breaksw
    
    case  -dbic_trace:
    case --dbic_trace:
      set dbic_trace = 'yes'
      breaksw
    
    case  -starman:
    case --starman:
      set starman = 'yes'
      breaksw
    
    case  -workers:
    case --workers:
      shift
      set workers = $1
      breaksw
    
   #case  -fast_cgi:
   #case --fast_cgi:
   #  set isock_server = 'isock_fastcgi'
   #  breaksw
      
    case  -pghost:
    case --pghost:
      shift
      setenv PGHOST $1
      breaksw
      
    case  -pgdatabase:
    case --pgdatabase:
      shift
      setenv PGDATABASE $1
      breaksw
      
    case  -pguser:
    case --pguser:
      shift
      setenv PGUSER $1
      breaksw
      
    case  -pgpassword:
    case --pgpassword:
      shift
      setenv PGPASSWORD $1
      breaksw
    
    case  -force:
    case --force:
      set force = 'yes'
      breaksw
    
    case  -pull:
    case --pull:
      set pull = 'yes'
      breaksw
    
    case  -dot:
    case --dot:
      set dot = 'yes'
      breaksw
    
    default:
      set argv2 = ( $argv2 $1 )
  endsw
  
  shift
end

#
# Hup.
#

if ( ( $?hup || $?tail ) && -f .script_isock ) then
  set work_root = `cat .script_isock | perl -ne '/ --work_root \s (\S+) /x and print $1'`
  set host      = `cat .script_isock | perl -ne '/ --port      \s (\S+) /x and print $1'`
  
  set isock_pid_file = "$work_root/ISOCK_LOGS/isock-${isock_name}-${host}.pid"
  set isock_log_file = "$work_root/ISOCK_LOGS/isock-${isock_name}-${host}.log"
  
  if ( -f $isock_pid_file ) then
    if ( $?hup ) then
      echo "kill -HUP `cat $isock_pid_file`"
      kill -HUP `cat $isock_pid_file`
    endif
    
    echo "tail -f $isock_log_file"
    tail -f $isock_log_file
  endif
  
  exit
endif

#
# Sanity.
#

if ( ! $?sock_root ) goto USAGE
if ( ! $?work_root ) goto USAGE

if ( ! $?PGPASSWORD ) then
  echo "Could not find any PGPASSWORD environment variable (or --pgpassword option)\!"
  
  goto FAILED
endif

#
# iSOCK.
#

set isock_root=$PWD

#
# Setup.
#

if ( ! $?isock_db ) then
  set isock_db = "$work_root/ISOCK_DB"
endif
set isock_logs = "$work_root/ISOCK_LOGS"
set isock_tmp  = "$work_root/ISOCK_TMP"

if ( ! -d $isock_db   ) mkdir $isock_db
if ( ! -d $isock_logs ) mkdir $isock_logs
if ( ! -d $isock_tmp  ) mkdir $isock_tmp

\rm -rf $isock_root/root/SOCK
( cd $isock_root/root ; ln -s $sock_root SOCK )

\rm -rf $isock_root/root/tmp
( cd $isock_root/root ; ln -s $isock_tmp tmp  )

\rm -rf $isock_root/root/db
( cd $isock_root/root ; ln -s $isock_db  db   )

if ( $?setup ) then
  goto PASSED
endif

#
# Prelude.
#

echo "[prelude] Checking if server can shutdown..."

set can_shutdown = `perl -Ilib -Iroot/SOCK/lib -MiSOCK -MiSOCK::Model::App -e 'print + iSOCK::Model::App->new->can_shutdown'`

if ( $status ) then
  echo "[prelude] | Broken."
  echo "[prelude] Failed\!"
  goto FAILED
endif

if ( ! $can_shutdown ) then
  if ( $?force ) then
    echo "[prelude] | Busy (overridden)."
  else
    echo "[prelude] | Busy (use $0 --dot --force to override)."
    echo "[prelude] Failed\!"
    goto FAILED
  endif
endif

echo "[prelude] Done."

#
# Pull.
#

if ( $?pull ) then
  echo "[prelude] Pulling..."
  
  git pull origin master --tags
  
  perl Makefile.PL
  make
  
  echo "[prelude] Done."
endif

#
# Helper.
#

echo "$dot_script_isock" > .script_isock
chmod 600 .script_isock

#
# Data.
#

if ( ! -f $isock_db/app.db ) then
  sqlite3 $isock_db/app.db < $isock_root/doc/app.sql
  
  echo "[invocation] Created app DB from SQL source"
endif

#
# Variables.
#

if ( $?proxy ) then
  setenv HTTPD_NAME $isock_name
  setenv HTTPD_HOST $isock_host
  setenv HTTPD_PORT $isock_port
  
  setenv ISOCK_NAME $isock_name
  setenv ISOCK_HOST $isock_host
  setenv ISOCK_PORT ${isock_port}0
else
  setenv ISOCK_NAME $isock_name
  setenv ISOCK_HOST $isock_host
  setenv ISOCK_PORT $isock_port
endif

set isock_log_file="$isock_logs/isock-${isock_name}-$ISOCK_PORT.log"
set isock_pid_file="$isock_logs/isock-${isock_name}-$ISOCK_PORT.pid"

#
# Proxy.
#

if ( $?http_proxy ) then
  unsetenv http_proxy
endif
if ( $?ftp_proxy ) then
  unsetenv ftp_proxy
endif

#
# Verbosity.
#

if ( -f $isock_log_file ) then
  mv -f $isock_log_file $isock_log_file,old
endif

if ( -l $sock_root ) then
  set sock_root_readlink = `perl -le "print ' (-> ' . readlink ( '$sock_root' ) . ')'"`
else
  set sock_root_readlink = ''
endif
if ( -l $isock_root ) then
  set isock_root_readlink = `perl -le "print ' (-> ' . readlink ( '$isock_root' ) . ')'"`
else
  set isock_root_readlink = ''
endif

set  sock_version = `perl -MYAML=LoadFile -le "print + LoadFile ( '$sock_root/MYMETA.yml' )->{version}"`
set isock_version = `perl -MYAML=LoadFile -le "print + LoadFile ( '$isock_root/MYMETA.yml' )->{version}"`

set date = `date`

echo "[invocation] Started on     : $date"                                            >  $isock_log_file

if ( $?proxy ) then
  echo "[invocation] Proxied by     : http://${HTTPD_NAME}:$HTTPD_PORT"               >  $isock_log_file
endif

echo "[invocation] Root for  SOCK : $sock_root $sock_version $sock_root_readlink"     >> $isock_log_file
echo "[invocation] Root for iSOCK : $isock_root $isock_version $isock_root_readlink"  >> $isock_log_file

#
# Proxy.
#

if ( $?proxy ) then
  setenv HTTPD_CONF "$isock_logs/httpd-${isock_name}:$isock_port.conf"
  setenv HTTPD_PID  "$isock_logs/httpd-${isock_name}:$isock_port.pid"
  setenv HTTPD_LOGE "$isock_logs/httpd-${isock_name}:$isock_port-error.log"
  setenv HTTPD_LOGA "$isock_logs/httpd-${isock_name}:$isock_port-access.log"
  
  rm -f $HTTPD_CONF
  
  echo 'server.modules       = ( "mod_proxy", "mod_accesslog" )' >> $HTTPD_CONF
  echo ""                                                        >> $HTTPD_CONF
  echo "server.name          = env.HTTPD_NAME"                   >> $HTTPD_CONF
  echo "server.bind          = env.HTTPD_HOST"                   >> $HTTPD_CONF
  echo "server.port          = env.HTTPD_PORT"                   >> $HTTPD_CONF
  echo ""                                                        >> $HTTPD_CONF
  echo "server.document-root = $isock_root + "\"/root\"          >> $HTTPD_CONF
  echo ""                                                        >> $HTTPD_CONF
  echo "server.errorlog      = env.HTTPD_LOGE"                   >> $HTTPD_CONF
  echo "accesslog.filename   = env.HTTPD_LOGA"                   >> $HTTPD_CONF
  echo ""                                                        >> $HTTPD_CONF
  echo "proxy.debug         = 0"                                 >> $HTTPD_CONF
  echo "proxy.server        = ("                                 >> $HTTPD_CONF
  echo "  "\"/\"" => ("                                          >> $HTTPD_CONF
  echo "    env.ISOCK_NAME => ("                                 >> $HTTPD_CONF
  echo "      "\"host\"" => env.ISOCK_HOST,"                     >> $HTTPD_CONF
  echo "      "\"port\"" => $ISOCK_PORT"                         >> $HTTPD_CONF
  echo "    )"                                                   >> $HTTPD_CONF
  echo "  )"                                                     >> $HTTPD_CONF
  echo ")"                                                       >> $HTTPD_CONF
  
  if ( ( ! $?dummy || $?kill ) ) then
    set httpd_pids = `ps -elf | fgrep "lighttpd" | fgrep ":$HTTPD_PORT" | fgrep -v 'fgrep' | awk '{print $4}'`
    
    if ( "$httpd_pids" != "" ) then
      echo "[invocation] Killing current qw( $httpd_pids ) proxy process(es)..."

      echo "[invocation] Command line   : kill -9 $httpd_pids"  >>  $isock_log_file
      if ( ! $?dummy ) then
        kill -9 $httpd_pids                                     >>& $isock_log_file
      endif

      echo "[invocation] Command line   : sleep 1"              >>  $isock_log_file
      if ( ! $?dummy ) then
        sleep 1                                                 >>& $isock_log_file
      endif

      rm -f $HTTPD_PID

      echo "[invocation] Done."
    else
      echo "[invocation] No proxy to kill."
    endif
  endif
  
  set lighttpd = `which lighttpd`
  
  echo "[invocation] Command line   : $lighttpd -f $HTTPD_CONF" >>  $isock_log_file
  if ( ! $?dummy && ! $?kill ) then
    echo "Spawning proxy..."
    
    $lighttpd -f $HTTPD_CONF -D                                 >>& $isock_log_file &
    
    echo $! > $HTTPD_PID
    
    echo "Done."
  endif
endif

#
# Options.
#

set isock_options = "--port $ISOCK_PORT --pidfile $isock_pid_file"

if ( $?debug ) then
  set isock_options = "--debug $isock_options"
endif

if ( $?devel ) then
  setenv ISOCK_DEVEL 1
endif

if ( $?fork ) then
  set isock_options = "--fork $isock_options"
endif

if ( ! $?proxy ) then
  set isock_options = "--keepalive $isock_options"

  if ( $restart == "yes" ) then
    set isock_options = "$isock_options --restart --restart_delay $restart_delay"
  endif
endif

#
# Path.
#

set path = ( $sock_root/tools $path )
rehash

#
# Core.
#

if ( ! $?dummy || $?kill ) then
  if ( -f $isock_pid_file ) then
    set isock_pid = `cat $isock_pid_file`
    
    if ( "$isock_pid" != "" ) then
      set isock_pids = `ps --pid $isock_pid --ppid $isock_pid -F | fgrep -v 'UID' | awk '{print $2}'`
    endif
  else
    if ( ! $?isock_pids ) then
      set isock_pids = `ps -elf | fgrep "script/$isock_server.pl" | fgrep " --port $ISOCK_PORT " | fgrep -v 'fgrep' | awk '{print $4}'`
    endif
  endif

  if ( $?isock_pids && ( "$isock_pids" != "" ) ) then
    echo "[invocation] Killing current qw( $isock_pids ) isock process(es)..."

    echo "[invocation] Command line   : kill -9 $isock_pids"                                                       >>  $isock_log_file     
    kill -9 $isock_pids                                                                                            >>& $isock_log_file     

    echo "[invocation] Command line   : sleep 1"                                                                   >>  $isock_log_file     
    sleep 1                                                                                                        >>& $isock_log_file     

    if ( -f $isock_pid_file ) then
      rm -f $isock_pid_file
    endif

    echo "[invocation] Done."
  else
    echo "[invocation] No isock to kill."
  endif
endif

if ( ! $?dummy && ! $?kill ) then
  echo "[invocation] Spawning isock..."
  
  if ( $?isock_parallel ) then
    setenv ISOCK_PARALLEL $isock_parallel
  endif
  
  setenv PERL5LIB $isock_root/lib:$sock_root/lib
  
  if ( $?dbic_trace ) then
    setenv DBIC_TRACE 1
  endif
  
  if ( $?proxy ) then
    setenv CATALYST_ENGINE HTTP::Prefork
  endif
  
  if ( $?starman ) then
    if ( $?debug ) then
      setenv CATALYST_DEBUG 1
     #setenv STARMAN_DEBUG  1
    endif
    
    set starman_switches = "--port $ISOCK_PORT --daemonize --app script/isock.app --pid $isock_pid_file --error-log $isock_log_file"
    
    if ( $?workers ) then
      set starman_switches = "$starman_switches --workers $workers"
    endif
    
    echo "[invocation] Command line   : starman $starman_switches"                                      >>  $isock_log_file
    starman $starman_switches
  else
    echo "[invocation] Command line   : perl $isock_root/script/$isock_server.pl $isock_options $argv2" >>  $isock_log_file
    perl $isock_root/script/$isock_server.pl $isock_options $argv2                                      >>& $isock_log_file &
  endif
  
  echo "[invocation] Done."
endif

#
# Hint.
#

if ( ! $?kill ) then
  sleep 3
  
  if ( $?proxy ) then
    echo "Connect to http://${HTTPD_NAME}:${HTTPD_PORT} server..."
  else
    echo "Connect to http://${ISOCK_NAME}:${ISOCK_PORT} server..."
  endif
  
  if ( $?tail ) then
          tail -f $isock_log_file
  else
    echo "tail -f $isock_log_file"
  endif
endif

#
# Labels.
#

PASSED:
exit 0

USAGE:
echo "-I- Usage: isock --sock_root <path> --work_root <path> [--setup] [--port <number|3333>] [--proxy] [--debug] [--devel] [--fork] [--parallel natural] [--starman [--workers <natural>]] [--force] [--pull] [--dot]"
exit 1

FAILED:
exit 1
